package valuecomusa.fijibus.eticket;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import android.widget.AdapterView.OnItemSelectedListener;
import valuecomusa.fijibus.eticket.shorthaul.R;
import valuecomusa.fijibus.eticket.db.shorthaul.BusinessDBHandler;
import valuecomusa.fijibus.eticket.db.shorthaul.GpsDBHandler;
import valuecomusa.fijibus.eticket.dto.GpsCurrentLocationValue;
import valuecomusa.fijibus.eticket.dto.StagesOfRouteValue;
import valuecomusa.fijibus.eticket.ws.TransactionValue;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

// import android.view.Menu;

public class TopUp extends SunbeamActivity
{
	private static int counter = 1;
    private String TAG = "TopUp";
    private Spinner cardType;
    private EditText approvalId;
    private EditText amount;
    private Button submit;
    CheckBox printReceipt;

    private StagesOfRouteValue currentLocation;
    private GpsDBHandler gpsDb;

	public TopUp()
	{
		TAG = TAG + "." + counter++;
		if(counter > 1000000)
			counter = 1;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.top_up);
        //---
		doCommon();
        //---
        TextView tv = (TextView) findViewById(R.id.topup_customer_id);
        tv.setText(WorkingSession.getInstance().currentPassenger.getFullName());

		cardType = (Spinner) findViewById(R.id.topup_card_type);
        List<String> listCardType = Arrays.asList("Cash", "Credit Card", "ATM Card");
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, listCardType);
        cardType.setAdapter(adapter);
        cardType.setOnItemSelectedListener(OnPayTypeSelected);
        cardType.setEnabled(false);
        //--
        approvalId = (EditText)findViewById(R.id.topup_approval_id);
        amount = (EditText) findViewById(R.id.topup_amount);
        //--
        Button btnClick = (Button)findViewById(R.id.topup_card_type_click);
        btnClick.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                cardType.performClick();
            }
        });
        btnClick.setEnabled(false);

        printReceipt = (CheckBox) findViewById(R.id.topup_print_receipt);
        printReceipt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b)
            {
                try
                {
                    InputMethodManager inputManager = (InputMethodManager)
                            getSystemService(INPUT_METHOD_SERVICE);

                    inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                            InputMethodManager.HIDE_NOT_ALWAYS);
                }
                catch(Exception ex){}

            }
        });

		submit = (Button) findViewById(R.id.topup_submit);
		submit.setOnClickListener(onSubmit);
        //--
        gpsDb = new GpsDBHandler(TopUp.this);
        GpsCurrentLocationValue currentGpsLocation = gpsDb.getCurrentLocation(
                WorkingSession.getInstance().setupJournal.ISN);
        if(currentGpsLocation != null)
        {
            Log.d(TAG, String.format("Current location: %d", currentGpsLocation.ClosestStage));
            BusinessDBHandler db = new BusinessDBHandler(TopUp.this);
            StagesOfRouteValue location = db.getStageWithStation(
                    WorkingSession.getInstance().setupJournal.RouteISN,
                    currentGpsLocation.ClosestStage,
                    currentGpsLocation.ClosestBusStation
            );
            if(location != null)
            {
                location.Latitude = currentGpsLocation.Latitude;
                location.Longitude = currentGpsLocation.Longitude;

                this.currentLocation = location;
            }
        }
	}

	@Override
	protected void onStart()
	{
		super.onStart();
		Log.d(TAG, "onStart...");
	}

	@Override
	protected void onPause()
	{
		super.onPause();
		Log.d(TAG, "onPause...");
	}

	@Override
	protected void onResume()
	{
		super.onResume();
		Log.d(TAG, "onResume...");
	}

	@Override
	protected void onDestroy()
	{
		super.onDestroy();
		Log.d(TAG, "onDestroy...");
	}

	@Override
	public void onBackPressed()
	{
		Log.d(TAG, "onBackPressed...");
		super.onBackPressed();
		finish();
	}

	OnItemSelectedListener OnPayTypeSelected = new OnItemSelectedListener()
	{
		public void onItemSelected(AdapterView<?> parent, View v, int pos,
				long row)
		{
            try
            {
                InputMethodManager inputManager = (InputMethodManager)
                        getSystemService(INPUT_METHOD_SERVICE);

                inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }
            catch(Exception ex){}

			String tmp = (String) parent.getItemAtPosition(pos);

			LinearLayout container = (LinearLayout)findViewById(R.id.topup_approval_id_container);
			if (tmp.equals("Cash"))
                container.setVisibility(View.GONE);
			else
                container.setVisibility(View.VISIBLE);
		}

		public void onNothingSelected(AdapterView<?> parent)
		{

		}
	};

	View.OnClickListener onSubmit = new View.OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
            try
            {
                InputMethodManager inputManager = (InputMethodManager)
                        getSystemService(INPUT_METHOD_SERVICE);

                inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
            }
            catch(Exception ex){}

            String approvalText = approvalId.getText().toString().trim();
            if(!cardType.getSelectedItem().toString().equals("Cash")
                    && approvalText.length() == 0)
            {
                WorkingSession.getInstance().ShowToast(TopUp.this, "Please enter Approval ID", Toast.LENGTH_SHORT);
                return;
            }
            String amountText = amount.getText().toString();
            try
            {
                if(amountText.length() == 0 || Double.parseDouble(amountText) == 0)
                {
                    WorkingSession.getInstance().ShowToast(TopUp.this, "Please enter Top Up amount", Toast.LENGTH_SHORT);
                    return;
                }
            }
            catch(Exception ex){}

            v.setEnabled(false);
            //--
            doTopUp();
		}
	};

    private void doTopUp()
    {
        try
        {
            String transactionDesc = "";
            if(!cardType.getSelectedItem().toString().equals("Cash"))
            {
                transactionDesc = String.format("Passenger top up,  Quick Transaction ID: %s",
                        approvalId.getText().toString());
            }
            /*String json = String.format("{'PayType' : '%s', 'Description' : '%s'}",
                    cardType.getSelectedItem().toString(),
                    transactionDesc);*/

            TransactionValue trans = WorkingSession.getInstance().CreateTransaction(
                    TopUp.this,
                    "TOP-UP",
                    cardType.getSelectedItem().toString(),
                    0,
                    0, 0,
                    Double.parseDouble(amount.getText().toString()),
                    null, //voucher
                    currentLocation,
                    null,
                    0,
                    0, 0, 0, 0, 0, 0,
                    null,
                    approvalId.getText().toString() + ";;;;;" + transactionDesc);

            //--
            if(trans == null)
            {
                WorkingSession.getInstance().ShowErrorDialog(
                        TopUp.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );
                submit.setEnabled(true);
                return;
            }
            //else{
              //  WorkingSession.getInstance().SAMUpdateCardBalance(
                       // (float)WorkingSession.getInstance().currentPassenger.CurrentBalance,
                        //(float) gpsDb.getCurrentLocation(WorkingSession.getInstance().setupJournal.ISN).Latitude,
                        //(float)gpsDb.getCurrentLocation(WorkingSession.getInstance().setupJournal.ISN).Longitude);
           // }
            //--
            BusinessDBHandler db = new BusinessDBHandler(TopUp.this);
            try
            {
                long rx = db.addTransaction(trans);
                trans.ISN = (int)rx;
            }
            catch (Exception ex)
            {
                WorkingSession.getInstance().ShowErrorDialog(
                        TopUp.this,
                        "Create Transaction Error",
                        "System Error.\nCould not create transaction, please contact your administrator."
                );
                submit.setEnabled(true);
                return;
            }

            WorkingSession.getInstance().ShowToast(TopUp.this, "Add transaction successful", Toast.LENGTH_SHORT);
            //---
            WorkingSession.getInstance().currentPassenger.CurrentBalance += trans.TopUpAmount;
            int x = db.updateMemberBalance(
                    WorkingSession.getInstance().currentPassenger.ISN,
                    WorkingSession.getInstance().currentPassenger.CurrentBalance);
            if(x > 0)
                WorkingSession.getInstance().ShowToast(TopUp.this, "Update customer balance successful", Toast.LENGTH_SHORT);
            else
                WorkingSession.getInstance().ShowToast(TopUp.this, "Update customer balance failed", Toast.LENGTH_SHORT);

            //--write to card
            WaitCardReaderOpenAndTapped();
            if(WorkingSession.getInstance().IsSmartCardTapped())
            {
                boolean rs = WorkingSession.getInstance().SAMUpdateCardBalance(
                        WorkingSession.getInstance().getLastTappedCardType(),
                        (int)(WorkingSession.getInstance().currentPassenger.CurrentBalance*100),
                        currentLocation!=null?(float)currentLocation.Latitude:0,
                        currentLocation!=null?(float)currentLocation.Longitude:0
                );
                if(rs)
                    Log.d(TAG, "[doTopUp] Write balance to card successful.");
                else
                    Log.d(TAG, "[doTopUp] Unable to write balance to card.");

            }


            // print receipt
            if (printReceipt.isChecked())
            {
                if(!PrintReceipt(trans))
                    onBackPressed();
            }
            else
                onBackPressed();
        }
        catch (Exception ex)
        {
            WorkingSession.getInstance().ShowToast(TopUp.this, ex.getMessage(),
                    Toast.LENGTH_LONG);
        }
    }

    private boolean WaitCardReaderOpenAndTapped()
    {
//        if(WorkingSession.getInstance().getSAM_NfcCardTapped() == -1)
//            WorkingSession.getInstance().OpenSAMCardReader(-1); //open with last information
        Log.d(TAG, "[WaitCardReaderOpenAndTapped] Waiting for card tapped in 10s");
        Date lastTest = new Date();
        long diffInSec = 0;
        try {
            do {
                Thread.sleep(200);
                long diffInMs = (new Date()).getTime() - lastTest.getTime();
                diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMs);
                lastTest = new Date();
            }
            while(!WorkingSession.getInstance().IsSmartCardTapped() && diffInSec < 10); //waiting for 10s
        }
        catch (Exception ex)
        {
            Log.e(TAG, "[WaitCardReaderOpenAndTapped] Exception: " + ex);
            ex.printStackTrace();
            return false;
        }
        if(diffInSec >= 10)
            return false;
        return true;
    }

    private String CreateReceiptContent(TransactionValue xx)
    {
        Date date = new Date();
        String receiptDate = Utilities.DateToString(date, "dd/MM/yyyy");
        String receiptTime = Utilities.DateToString(date, "hh:mm a");

        /*String content = "Powered by: BulamyFiji (BMF)"
                + "\nSunbeam Transport (Fiji) Ltd"
                + "\nLautoka, Fiji Islands"
                + "\nTIN #: 35846990930"
                + "\n********************************"
                + "\nDate     : " + receiptDate
                + "\nDept Time: " + receiptTime
                + "\nTop Up   : " + WorkingSession.getInstance().decimalFormat.format(xx.TopUpAmount)
                + "\nAppvl ID : " + approvalId.getText().toString()
                + "\n---"
                + "\nTran ID  : " + xx.TransactionID
                + "\nVehicle  : " + WorkingSession.getInstance().journalBus.BusNumber
                + "\nConductor: " + WorkingSession.getInstance().loggedInConductor.UserName
                + "\n---"
                + "\nCustomer : " + WorkingSession.getInstance().currentPassenger.getFullName()
                + "\nACC #    : xxxx" + WorkingSession.getInstance().currentPassenger.CardNumber.substring(
                WorkingSession.getInstance().currentPassenger.CardNumber.length()-4)
                + "\nBalance  : " + WorkingSession.getInstance().decimalFormat.format(
                WorkingSession.getInstance().currentPassenger.CurrentBalance)
                + "\n********************************"
                + "\nThank you"
                + "\n--------------------------------\n";

        */

        String content = Utilities.StringAlignCenter(48, "BulaMy(Fiji) - BMF etikite  ") //+ "\n"
                + Utilities.StringAlignCenter(48, "BMF Make It Your Choice")
                + Utilities.StringAlignCenter(48, "www.bulamyfiji.com")
                + "\n\n"
                + Utilities.StringAlignLeftRight(48,
                    "Top Up Location: " + xx.Origination,
                    " "
                    ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Top Up Amount: " + WorkingSession.getInstance().decimalFormat.format(xx.TopUpAmount),
                    "Bus Reg.: " + WorkingSession.getInstance().journalBus.BusNumber
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "Balance: " + WorkingSession.getInstance().decimalFormat.format(
                        WorkingSession.getInstance().currentPassenger.CurrentBalance),
                    "Driver: " + WorkingSession.getInstance().journalDriver.FullName
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "TXN ID: " +  xx.TransactionID,
                    "Company: DeeCees Fiji Ltd"
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "ACCT Name: " +  WorkingSession.getInstance().currentPassenger.getFullName(),
                    "TIN: 12683467161"
                ) + "\n"
                + Utilities.StringAlignLeftRight(48,
                    "ACCT #: " +  WorkingSession.getInstance().currentPassenger.CardNumber,
                    "Issued: " + receiptDate + ", " + receiptTime
                ) + "\n"
                + "\nThank you\n\n";

        return content;
    }

    private boolean PrintReceipt(TransactionValue xx)
    {
        Date date = new Date();
        String receiptDate = Utilities.DateToString(date, "dd.MM.yyyy");
        String receiptTime = Utilities.DateToString(date, "hh:mm a");

        String content = CreateReceiptContent(xx);

        int rs = WorkingSession.getInstance().PreparePrintReceiptWifi(TopUp.this, content, printReceiptCallback);

        if (rs == Declarations.NO_WIFI_PRINTER_SETUP)
            WorkingSession.getInstance().ShowToast(TopUp.this, "No printer selected. Please setup one.", Toast.LENGTH_LONG);
        else if (rs == Declarations.PRINT_RECEIPT_ERROR)
        {
            WorkingSession.getInstance().ShowToast(TopUp.this, "Print receipt failed.", Toast.LENGTH_LONG);
        }

        return rs == Declarations.PRINT_RECEIPT_WAITING;
    }
/*
    private final Handler printReceiptCallback = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case Declarations.BLUETOOTH_CONNECTING:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Connecting to printer...", Toast.LENGTH_SHORT);
                    break;
                case Declarations.BLUETOOTH_CONNECTED:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Connect successful", Toast.LENGTH_SHORT);
                    break;
                case Declarations.BLUETOOTH_UNABLE_CONNECT:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Unable connect to printer", Toast.LENGTH_SHORT);
                    onBackPressed();
                    break;
                case Declarations.PRINT_RECEIPT_ERROR:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Print receipt failed", Toast.LENGTH_SHORT);
                    onBackPressed();
                    break;
                case Declarations.PRINT_RECEIPT_SUCCESSFUL:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Print receipt successful", Toast.LENGTH_SHORT);
                    onBackPressed();
                    break;
            }
        }
    };*/

    private final Handler printReceiptCallback = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
				case Declarations.WIFI_PRINTER_CONNECTED:
					WorkingSession.getInstance().ShowToast(TopUp.this,
							"Printer connected", Toast.LENGTH_SHORT);
					WorkingSession.getInstance().PrintReceipt();
					break;

                case Declarations.WIFI_PRINTER_CONNECTED_ERR:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Unable connect to printer", Toast.LENGTH_SHORT);
					onBackPressed();
                    break;
                case Declarations.WIFI_PRINTER_SEND_FAILED:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Unable send data to printer", Toast.LENGTH_SHORT);
					onBackPressed();
                    break;
                case Declarations.PRINT_RECEIPT_SUCCESSFUL:
                    WorkingSession.getInstance().ShowToast(TopUp.this,
                            "Print receipt successful", Toast.LENGTH_SHORT);
                    onBackPressed();
                    break;
            }
        }
    };

}
